home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / CUGUK / COMMS / C011.ZIP / LAR.C < prev    next >
Text File  |  1990-01-19  |  17KB  |  724 lines

  1.  
  2. /********************************************************************
  3.  * C Users Group (U.K) C Source Code Library File CUGLIB.011        *
  4.  * Inquiries to: M. Houston, 36 Whetstone Clo. Farquhar Rd.         *
  5.  * Edgbaston, Birmingham B15 2QN ENGLAND                *
  6.  ********************************************************************
  7.  * File name: lar.c
  8.  * Program name: lar
  9.  * Source of file: The Public Domain Software Library.
  10.  * Purpose: LU format library manager
  11.  * Changes: <who what when & why major changes have been made>      
  12.  ********************************************************************/
  13.  
  14. /*
  15.  * Lar - LU format library file maintainer
  16.  *     by Stephen C. Hemminger
  17.  *     linus!sch or sch @Mitre-Bedford MA
  18.  *
  19.  *    Lattice version T. Jennings 1 Dec 83
  20.  *
  21.  * DESCRIPTION
  22.  *    Lar is a program to manipulate CP/M LU format libraries.
  23.  *    The original CP/M library program LU is the product
  24.  *    of Gary P. Novosielski. The primary use of lar is to combine several
  25.  *    files together for upload/download to a personal computer.
  26.  *
  27.  * Usage: lar key library [files] ...
  28.  *
  29.  * Key functions are:
  30.  * u - Update, add files to library    (also creates new libraries)
  31.  * t - Table of contents
  32.  * e - Extract files from library
  33.  * p - Print files in library
  34.  * d - Delete files in library
  35.  * r - Reorganize library
  36.  *
  37.  * EXAMPLES:
  38.  * lar t foo.lbr        list all files in FOO.LBR
  39.  * lar e foo.lbr 1.c 2.c    extract files 1.c, 2.c from FOO.LBR
  40.  * lar p foo.lbr 1.c        display 1.c from FOO.LBR
  41.  * lar u foo.lbr 1.c 2.c 3.c     add or replace files in FOO.LBR
  42.  *
  43.  * When creating a new library, you will be prompted for the maximum
  44.  * number of entries it can contain. Assuming NEW.LBR doen't exist ...
  45.  * lar u new.lbr        create an empty library
  46.  * lar u new.lbr a.c,b.c,d.c    create NEW.LBR, add files.
  47.  *
  48.  * The Reorganize option causes <lbrfile>.tmp to be created, and
  49.  * the contents of the old library to be copied into it.
  50.  *
  51.  * This program is public domain software, no warranty intended or
  52.  * implied.
  53.  *
  54.  *
  55.  * PORTABILITY
  56.  *    The original version by Stephan C. Hemminger was set up for 
  57.  *    Version 7 UNIX, and was not useable as is. It has been hacked
  58.  *    to fit the Lattice C compiler for MSDOS and CP/M-86. The basic
  59.  *    problems were: fread() and fwrite() incompatibility, no 
  60.  *    text/binary differntiation problem in MSDOS, structure alignment
  61.  *    problems, Lattice vs. UNIX vs. BDS. Lattice does not gaurentee
  62.  *    structure element alignment (i.e. an int after a char is not 
  63.  *    necessarily the next byte address) and therefore there is a serious
  64.  *    kludge in the structure definition for the library.
  65.  *
  66.  *    Also, I have made random changes to the source merely to reflect
  67.  *    my programming taste; the original code was quite good. I have also
  68.  *    changed the wording of some errors, etc more in line with the current
  69.  *    flavor of messages in the micro environment. The original Verbose
  70.  *    flag option was removed, and made the default. No need to suppress
  71.  *    what few messages and text there is.
  72.  *
  73.  *    As mentioned before, ther is no problem with text or binary files;
  74.  *     they are treated identically. Control-Z characters are added to the
  75.  *    end of all files to round it up to a multiple of 128 bytes.
  76.  *
  77.  *    Note that all files are kept as multiples of 128 bytes, to be 
  78.  *    compatible with the CP/M utility LU. This may present a problem
  79.  *    with certain data files, but will be OK for text and .COM files
  80.  *    anyways, and probably most other files.
  81.  *
  82.  * NOTES ON MSDOS VERSION
  83.  *    There is an annoying problem with this program when run under MSDOS.
  84.  *    If for some reason an update should fail (disk full, not enough slots)
  85.  *    the file will not be closed, and therefore there will be orphan data
  86.  *    blocks hanging around. Do CHKDSK\F to fix this. The problem is with
  87.  *    the use of the error() function, which is called throughout and just
  88.  *    exits to DOS after reporting the error, with out closing the file.
  89.  *    Check your .LBR file after this happens; it may be bad. Do a reorganize
  90.  *    to fix if necessary.
  91.  *
  92.  *    To compensate for this, I also fixed a bug in the original version. If
  93.  *    an empty library was created, it could not be used. One had to be 
  94.  *    created with at least one file. The problem was that the directory-
  95.  *    getter function (getdir) always read 16 bytes more than the actual
  96.  *    size of the directory; this was OK if there was files in the library.
  97.  *
  98.  * * Unix is a trademark of Bell Labs.
  99.  * ** CP/M is a trademark of Digital Research.
  100.  */
  101.  
  102. #include <stdio.h>
  103. #include <ctype.h>
  104.  
  105. /* There is no tell(), but lseek() does the same thing. For some reason seek()
  106. is called lseek. Fix this minor annoyance. */
  107.  
  108. long lseek();
  109. #define tell(f) lseek(f,0L,1)
  110. #define seek lseek
  111.  
  112. /* Library file status values: */
  113.  
  114. #define ACTIVE 0
  115. #define UNUSED    0xff
  116. #define    DELETED    0xfe
  117. #define    CTRLZ    0x1a
  118.  
  119.  
  120. #define    MAXFILES 256
  121. #define    SECTOR 128
  122. #define    DSIZE (sizeof(struct ludir))
  123. #define    SLOTS_SEC (SECTOR/DSIZE)
  124. #define    equal(s1, s2) (    strcmp(s1,s2) == 0 )
  125. #define false 0
  126. #define    true 1
  127. #define    bool int
  128.  
  129. /* Globals */
  130. char *fname[MAXFILES];
  131. bool ftouched[MAXFILES];
  132.  
  133. /* This bullshit (or something like it) is necessary because the byte order
  134. of structure elements is not garenteed in Lattice C, i.e. an INT right after
  135. an CHAR is not necessarily &( CHAR + 1), i.e. there's a fill byte after the
  136. CHAR to put it on a word boundary.
  137.  
  138. This is incredibly gross, and forces proper alignment for Lattice ONLY !!! */
  139.  
  140. struct ludir {            /* internal dir. stucture, 32 bytes */
  141.     char l_l[12];        /* 12 byte filename: */
  142. #define l_stat l_l[0]        /* status of file, */
  143. #define l_name l_l[1]        /* filename, */
  144. #define l_ext l_l[9]        /* extention, */
  145.     int l_off;        /* offset in library, */
  146.     int l_len;        /* length of file, */
  147.     int l_fill[8];        /* 16 byte filler, */
  148. } ldir[MAXFILES];
  149.  
  150. int errcnt, nfiles, nslots;
  151.  
  152. char *getname(), *sprintf();
  153.  
  154. main (argc, argv)
  155. int argc;
  156. char **argv;
  157. {
  158. char *flagp;
  159. char *aname;
  160.  
  161.     if (argc < 3)
  162.         help ();
  163.     aname =    argv[2];    /* name of LBR file, */
  164.     filenames (argc, argv);
  165.  
  166.     switch (tolower(*argv[1])) {
  167.     case 'u': 
  168.         update(aname);
  169.         break;
  170.     case 't': 
  171.         table(aname);
  172.         break;
  173.     case 'e': 
  174.         extract(aname);
  175.         break;
  176.     case 'p': 
  177.         print(aname);
  178.         break;
  179.     case 'd': 
  180.         delete(aname);
  181.         break;
  182.     case 'r': 
  183.         reorg(aname);
  184.         break;
  185.         break;
  186.     default: 
  187.         help();
  188.     }
  189.     exit();
  190. }
  191.  
  192. /* print error message and exit    */
  193. help ()    {
  194.     printf ("Usage: LAR [utepdr] library [files] ...\n");
  195.     printf ("Functions are:\n\tu - Update, add files to library\n");
  196.     printf ("\tt - Table of contents\n");
  197.      printf ("\te - Extract files from library\n");
  198.     printf ("\tp - Print files in library\n");
  199.     printf ("\td - Delete files in library\n");
  200.     printf ("\tr - Reorganize library\n");
  201.     exit (1);
  202. }
  203.  
  204. error (str)
  205. char *str;
  206. {
  207.     printf ("LAR: %s\n", str);
  208.     exit (1);
  209. }
  210.  
  211. cant (name)
  212. char *name;
  213. {
  214.  
  215.     printf ("%s: File open error\n", name);
  216.     exit (1);
  217. }
  218.  
  219. /* Get file names, check for dups, and initialize */
  220.  
  221. filenames (ac, av)
  222. char **av;
  223. {
  224.  register int i, j;
  225.  
  226.     errcnt = 0;
  227.     for (i = 0; i < ac - 3; i++) {
  228.     fname[i] = av[i + 3];
  229.     ftouched[i] = false;
  230.     if (i == MAXFILES)
  231.         error ("Too many file names.");
  232.     }
  233.     fname[i] = NULL;
  234.     nfiles = i;
  235.     for (i = 0; i < nfiles; i++)
  236.     for (j = i + 1; j < nfiles; j++)
  237.         if (equal (fname[i], fname[j])) {
  238.         printf ("%s", fname[i]);
  239.         error (": duplicate file name");
  240.         }
  241. }
  242.  
  243. table (lib)
  244. char *lib;
  245. {
  246. int lfd;
  247. register int i, total;
  248. int active = 0, unused = 0, deleted = 0;
  249. char *uname;
  250.  
  251.     if ((lfd= open(lib,0x8002)) == -1)
  252.         cant (lib);
  253.  
  254.     getdir (lfd);
  255.     total =    ldir[0].l_len;
  256.     printf("Name         Index    Length (sectors)\n");
  257.     printf("Directory    %4u    %6u\n", total, total);
  258.  
  259.     for (i = 1; i < nslots;    i++)
  260.         switch(ldir[i].l_stat) {
  261.         case ACTIVE:
  262.             active++;
  263.             uname = getname(&ldir[i].l_name, &ldir[i].l_ext);
  264.             total += ldir[i].l_len;
  265.             printf ("%-12s %4u   %7u\n", uname,ldir[i].l_off,ldir[i].l_len);
  266.             break;
  267.         case UNUSED:
  268.             unused++;
  269.             break;
  270.         default:
  271.             deleted++;
  272.     }
  273.     printf("-----------------------------\n");
  274.     printf("Total sectors       %7u\n", total);
  275.     printf("\nLibrary %s has %u slots, %u deleted, %u active, %u unused\n",
  276.         lib, nslots, deleted, active, unused);
  277.     close (lfd);
  278.     not_found ();
  279. }
  280.  
  281. getdir (f)
  282. int f;
  283. {
  284. int cnt;
  285.  
  286.     seek(f,0L,0);
  287.     if (read(f,&ldir[0],DSIZE) != DSIZE)    /* read 1st entry to find */
  288.         error ("No directory\n");    /* number of slots, */
  289.  
  290.     nslots = ldir[0].l_len * SLOTS_SEC;
  291.     cnt= DSIZE * (nslots - 1);        /* already read one slot, */
  292.  
  293.     if (read(f,&ldir[1],cnt) != cnt)
  294.         error ("Can't read directory - is it a library?");
  295. }
  296.  
  297. putdir (f)
  298. int f;
  299. {
  300.  
  301.     seek(f,0L,0);
  302.     if (write(f,&ldir,nslots * DSIZE) != (nslots * DSIZE))
  303.         error ("Can't write directory - library may be botched");
  304. }
  305.  
  306. initdir    (f)
  307. int f;
  308. {
  309. register int i;
  310. int numsecs;
  311. char line[80];
  312.  
  313.     for (;;) {
  314.         cprintf ("Number of slots to allocate: ");
  315.         getstring(line);
  316.         cprintf("\r\n");
  317.         nslots = atoi (line);
  318.         if (nslots < 1)
  319.             printf ("Must have at least one!\n");
  320.         else if (nslots > MAXFILES)
  321.             printf    ("Too many slots\n");
  322.         else
  323.             break;
  324.     }
  325.  
  326.     numsecs    = nslots / SLOTS_SEC;
  327.     nslots = numsecs * SLOTS_SEC;
  328.  
  329.     for (i = 0; i < nslots;    i++) {
  330.         ldir[i].l_stat= UNUSED;
  331.         blank_fill(&ldir[i].l_name,8);
  332.         blank_fill(&ldir[i].l_ext,3);
  333.     }
  334.     ldir[0].l_stat = ACTIVE;
  335.     ldir[0].l_len= numsecs;
  336.  
  337.     putdir (f);
  338. }
  339. /* Fill    an array with blanks, no trailing null.    */
  340. blank_fill(s,n)
  341. char *s;
  342. int n;
  343. {
  344.     while (n--) *s++= ' ';
  345. }
  346. /* convert nm.ex to a Unix style string */
  347.  
  348. char *getname (nm, ex)
  349. char *nm, *ex;
  350. {
  351. static char namebuf[14];
  352. int i,j;
  353.  
  354.     for (i= 0; (i < 8) && (nm[i] != ' '); i++)
  355.         namebuf[i]= tolower(nm[i]);
  356.     j= i;
  357.     namebuf[j++]= '.';
  358.  
  359.     for (i= 0; (i < 3) && (ex[i] != ' '); i++)
  360.         namebuf[j++]= tolower(ex[i]);
  361.     namebuf[j]= '\0';
  362.  
  363.     return namebuf;
  364. }
  365.  
  366. putname (cpmname, unixname)
  367. char *cpmname, *unixname;
  368. {
  369.  
  370.     cvt_to_fcb(unixname,cpmname);
  371. }
  372.  
  373. /* filarg - check if name matches argument list */
  374. filarg (name)
  375. char *name;
  376. {
  377. register int i;
  378.  
  379.     if (nfiles <= 0)
  380.     return 1;
  381.  
  382.     for (i = 0; i < nfiles;    i++)
  383.     if (equal (name, fname[i])) {
  384.         ftouched[i] = true;
  385.         return    1;
  386.     }
  387.  
  388.     return 0;
  389. }
  390.  
  391. not_found () {
  392. register int i;
  393.  
  394.     for (i = 0; i < nfiles;    i++)
  395.     if (!ftouched[i]) {
  396.         printf ("%s: not in library.\n", fname[i]);
  397.         errcnt++;
  398.     }
  399. }
  400.  
  401. extract(name)
  402. char *name;
  403. {
  404.     getfiles(name, false);
  405. }
  406.  
  407. print(name)
  408. char *name;
  409. {
  410.     getfiles(name, true);
  411. }
  412.  
  413. getfiles (name,    pflag)
  414. char *name;
  415. bool pflag;
  416. {
  417. int lfd, ofd;
  418. register int i;
  419. char *unixname;
  420.  
  421.     if ((lfd= open(name,0x8002)) == -1)
  422.         cant (name);
  423.     getdir (lfd);
  424.  
  425.     for (i = 1; i < nslots;    i++) {
  426.     if(ldir[i].l_stat != ACTIVE)
  427.         continue;
  428.     unixname = getname (&ldir[i].l_name, &ldir[i].l_ext);
  429.     if (!filarg (unixname))
  430.         continue;
  431.     printf("Extracting %s\n", unixname);
  432.     if (pflag)
  433.         ofd= open("CON",0x8002);
  434.     else
  435.         ofd= creat(unixname,0x8002);
  436.     if (ofd == -1) {
  437.         printf (" - can't create output file\n");
  438.         errcnt++;
  439.     }
  440.     else {
  441.         seek (lfd, (long) ldir[i].l_off * SECTOR,0);
  442.         acopy (lfd, ofd, ldir[i].l_len);
  443.         if (!pflag)
  444.             close (ofd);
  445.     }
  446.     }
  447.     close (lfd);
  448.     not_found ();
  449. }
  450.  
  451. acopy (fdi, fdo, nsecs)
  452. int fdi, fdo;
  453. unsigned nsecs;
  454. {
  455. char buf[SECTOR];
  456.  
  457.     while( nsecs-- != 0) {
  458.         if (read(fdi,buf,SECTOR) != SECTOR)
  459.             error("Can't read");
  460.         if (write(fdo,buf,SECTOR) != SECTOR)
  461.             error ("write error (acopy)");
  462.     }
  463. }
  464.  
  465. update (name)
  466. char *name;
  467. {
  468. int lfd;
  469. register int i;
  470.  
  471.     if ((lfd = open (name,0x8002)) == -1) {
  472.         if ((lfd = creat(name, 2)) == -1)
  473.             cant (name);
  474.         initdir (lfd);
  475.  
  476. /* We shouldnt have to do this, but writes to the (new) file fail otherwise. */
  477.  
  478.         close(lfd);        /* close it, */
  479.         lfd= open(name,0x8002);    /* reopen it, */
  480.     } 
  481.     getdir (lfd);            /* read directory, */
  482.  
  483.     for (i = 0; (i < nfiles) && (errcnt == 0); i++)
  484.         addfil (fname[i], lfd);
  485.     if (errcnt != 0)
  486.         printf ("fatal errors - last file may be bad\n");
  487.     putdir (lfd);
  488.     close (lfd);
  489. }
  490.  
  491. addfil (name, lfd)
  492. char *name;
  493. int lfd;
  494. {
  495. int ifd;
  496. register int secoffs, numsecs;
  497. register int i;
  498.  
  499.     if ((ifd= open(name,0x8002)) == -1) {
  500.         printf ("%s: can't find to add\n",name);
  501.         errcnt++;
  502.         return;
  503.     }
  504.     for (i = 0; i < nslots;    i++) {
  505.         if (equal( getname (&ldir[i].l_name, &ldir[i].l_ext), name) ) {
  506.             printf("Updating existing file %s\n",name);
  507.             break;
  508.         }
  509.         if (ldir[i].l_stat != ACTIVE) {
  510.             printf("Adding new file %s\n",name);
  511.             break;
  512.         }
  513.     }
  514.     if (i >= nslots) {
  515.         printf("Can't add %s, library is full\n",name);
  516.         errcnt++;
  517.         return;
  518.     }
  519.  
  520.     ldir[i].l_stat = ACTIVE;
  521.     putname    (&ldir[i].l_name, name);
  522.     seek(lfd, 0L, 2);        /* append to end */
  523.     secoffs    = tell(lfd) / SECTOR;
  524.  
  525.     seek(lfd,0L,2);            /* clear write error? */
  526.  
  527.     ldir[i].l_off= secoffs;
  528.     numsecs = fcopy (ifd, lfd);
  529.     ldir[i].l_len= numsecs;
  530.     close (ifd);
  531. }
  532.  
  533. fcopy (ifd, ofd)
  534. int ifd, ofd;
  535. {
  536. int total = 0;
  537. int i,n;
  538. char sectorbuf[SECTOR];
  539.  
  540.  
  541.     while (n= read(ifd,sectorbuf,SECTOR) ) {
  542.         if (n != SECTOR) {
  543.             for (i    = n; i < SECTOR; i++)
  544.                 sectorbuf[i] = CTRLZ;
  545.         }
  546.         if (write(ofd,sectorbuf,SECTOR) != SECTOR)
  547.             error("write error (fcopy)");
  548.         ++total;
  549.     }
  550.     return total;
  551. }
  552.  
  553. delete (lname)
  554. char *lname;
  555. {
  556. int f;
  557. register int i;
  558.  
  559.     if ((f= open(lname,0x8002)) == -1)
  560.         cant (lname);
  561.  
  562.     if (nfiles <= 0)
  563.         error("delete by name only");
  564.  
  565.     getdir (f);
  566.     for (i = 0; i < nslots;    i++) {
  567.         if (!filarg ( getname (&ldir[i].l_name, &ldir[i].l_ext)))
  568.             continue;
  569.         ldir[i].l_stat = DELETED;
  570.     }
  571.  
  572.     not_found();
  573.     if (errcnt > 0)
  574.         printf ("errors - library not updated\n");
  575.     else
  576.         putdir (f);
  577.     close (f);
  578. }
  579.  
  580. reorg (name)
  581. char *name;
  582. {
  583. int olib, nlib;
  584. int oldsize;
  585. register int i, j;
  586. struct ludir odir[MAXFILES];
  587. char tmpname[SECTOR];
  588.  
  589.     for (i= 0; (i < 8) && (name[i] != '.'); i++) /* copy filename, */
  590.         tmpname[i]= name[i];        /* strip off extention, */
  591.     tmpname[i]= '\0';
  592.     strcat(tmpname,".tmp");            /* make new name, */
  593.  
  594.     if ((olib= open(name,0x8002)) == -1)
  595.         cant(name);
  596.  
  597.     if ((nlib= creat(tmpname,0x8002)) == -1)
  598.         cant(tmpname);
  599.  
  600.     getdir(olib);
  601.     printf("Old library has %d slots\n", oldsize = nslots);
  602.     for(i = 0; i < nslots ; i++)
  603.         copymem( (char    *) &odir[i], (char *) &ldir[i],
  604.             sizeof(struct ludir));
  605.     initdir(nlib);
  606.     errcnt = 0;
  607.  
  608.     for (i = j = 1; i < oldsize; i++)
  609.     if( odir[i].l_stat == ACTIVE ) {
  610.         printf("Copying: %-8.8s.%3.3s\n",&odir[i].l_name, &odir[i].l_ext);
  611.         copyentry( &odir[i], olib, &ldir[j], nlib);
  612.         if (++j >= nslots) {
  613.             errcnt++;
  614.             printf("Not enough room in new library\n");
  615.             break;
  616.         }
  617.     }
  618.  
  619.     close(olib);
  620.     putdir(nlib);
  621.     close (nlib);
  622.  
  623.     if (errcnt == 0) {
  624.         unlink(name);            /* delete orig file, */
  625.         link(tmpname,name);        /* rename it, */
  626.     } else {
  627.         printf("Errors, library not updated\n");
  628.         unlink(tmpname);
  629.     }
  630. }
  631.  
  632. copyentry( old, of, new, nf )
  633. struct ludir *old, *new;
  634. int of, nf;
  635. {
  636.  
  637.     register int secoffs, numsecs;
  638.     char buf[SECTOR];
  639.  
  640.     new->l_stat = ACTIVE;
  641.     copymem(&new->l_name, &old->l_name, 8);
  642.     copymem(&new->l_ext, &old->l_ext, 3);
  643.     seek(of, (long) (old->l_off * SECTOR), 0);
  644.     seek(nf, 0L, 2);
  645.     secoffs = tell(nf) / SECTOR;
  646.  
  647.     seek(nf,0L,2);        /* clear write error? */
  648.  
  649.     new->l_off= secoffs;
  650.     numsecs    = old->l_len;
  651.     new->l_len= numsecs;
  652.  
  653.     while(numsecs--    != 0) {
  654.         if (read(of,buf,SECTOR) != SECTOR)
  655.             error("read error");
  656.         if (write(nf,buf,SECTOR) != SECTOR)
  657.             error("write error (copyentry)");
  658.     }
  659. }
  660.  
  661. copymem(dst, src, n)
  662. register char *dst, *src;
  663. register unsigned int n;
  664. {
  665.     while(n-- != 0)
  666.         *dst++ = *src++;
  667. }
  668. /* ATOI() function missing from Lattice C. From Kernighan and Richie. */
  669.  
  670. atoi(s)
  671. char s[];
  672. {
  673. int i,n;
  674.  
  675.     n= 0;
  676.     for (i= 0; s[i] >= '0' && s[i] <= '9'; ++i) 
  677.         n= 10*n + s[i]-'0';
  678.     return(n);
  679. }
  680. /* Missing Lattice C function: File rename
  681.  
  682.     error= link(oldname,newname); */
  683.  
  684. link(old,new)
  685. char *old,*new;
  686. {
  687. char fcb[36];
  688. int i;
  689. char *p;
  690.  
  691.     for (i= 0; i < sizeof(fcb); i++)    /* clear it out first, */
  692.         fcb[i]= '\0';
  693.  
  694.     cvt_to_fcb(old,&fcb[1]);        /* first name, */
  695.     cvt_to_fcb(new,&fcb[17]);        /* new name, */
  696.     return(bdos(23,&fcb) == 0xff);        /* do it. */
  697. }
  698.  
  699. /* Convert a normal asciz string to MSDOS/CPM FCB format. Make the filename
  700. portion 8 characters, extention 3 maximum. */
  701.  
  702. cvt_to_fcb(inname,outname)
  703. char *inname;
  704. char outname[];
  705. {
  706. char c;
  707. int i;
  708.  
  709.     for (i= 0; i < 11; i++)
  710.         outname[i]= ' ';        /* clear out name, */
  711.     for (i= 0; i < 11; i++) {
  712.         if (*inname == '\0')        /* if null, */
  713.             outname[i]= ' ';    /* pad with blanks, */
  714.         else if (*inname == '.') {    /* if a dot, */
  715.             ++inname;        /* skip it, */
  716.             i= 7;            /* skip to extention, */
  717.         } else {
  718.             outname[i]= toupper(*inname);
  719.             ++inname;
  720.         }
  721.     }
  722.     return;
  723. }
  724.